#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QFont>
#include <QFile>
#include <QDebug>
#include <QDebug>
#include <QEvent>
#include <QPoint>
#include <QPixmap>
#include <QMovie>
#include <QToolTip>
#include <QDateTime>
#include <QSettings>
#include <QListView>
#include <QMetaType>
#include <QClipboard>
#include <QJsonArray>
#include <QScrollBar>
#include <QBoxLayout>
#include <QFileDialog>
#include <QFontDialog>
#include <QJsonObject>
#include <QInputDialog>
#include <QActionGroup>
#include <QJsonDocument>
#include <QCloseEvent>
#include <QJsonParseError>
#include <QDesktopServices>
#include <QFileIconProvider>
#include <QRegularExpression>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include "VLua.h"
#include "VFile.h"
#include "VGlobal.h"
#include "VScintilla.h"
#include "VStartPage.h"
#include "VDockWidget.h"
#include "VInputDialog.h"
#include "VSaveQuestion.h"
#include "VScintillaEx.h"
#include "VDialogRemove.h"
#include "VSettingDialog.h"
#include "VJsonItemWidget.h"
#include "VTitleBarWidget.h"
#include "VJsonSettingDilg.h"
#include "VInputListWidget.h"
#include "VRemoveFileDialog.h"
#include "VModuleSettingDlg.h"
#include "VNewProjectDialog.h"
#include "VOutputInformation.h"
#include "VQscilexerCppAttach.h"
#include "VProjectAttributeDialog.h"



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    _unlock_timer(this)
{
    ui->setupUi(this);
    QWidget* p = takeCentralWidget();
    if(p) delete p;

    this->installEventFilter(this);
    QMainWindow::setDockNestingEnabled(true);

    init_qss();
    init_icon_path();
    init_action();
    init_action_icon();
    init_action_shortCut();
    init_background_system();
    init_ui();
    init_lock_timer();
    readSettings();
    init_start_param();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slot_show_input_calltip(QList<VWords*> list)
{
//    qDebug() << "slot_show_input_calltip";
    // 释放内存

    for(int i=0; i<VGlobal::input_tip->count(); i++)
    {
        auto item = VGlobal::input_tip->item(i);
        VWords *ptr = (VWords*)(item->data(Qt::UserRole).value<void*>());
        if(ptr != nullptr)
        {
            delete ptr;
            item->setData(Qt::UserRole, QVariant::fromValue((void*)nullptr));
        }
    }

    VGlobal::input_tip->clear();

    foreach (VWords* p_word, list)
    {
        QListWidgetItem *item = new QListWidgetItem(VGlobal::input_tip);
        item->setIcon(QIcon(get_calltip_icon(p_word->_kind)));
        item->setText(calltip_item_text(p_word));
        item->setData(Qt::UserRole, QVariant::fromValue((void*)p_word));
    }

    VScintillaEx *scintilla = get_current_active_scintilla();
    qDebug() << scintilla << "count:" << list.count();
    if(scintilla != nullptr)
    {
        if (VGlobal::input_tip->count() > 0)
        {
            int cursor_pos = scintilla->SendScintilla(QsciScintilla::SCI_GETCURRENTPOS);
            QPoint point;

            point.setX(scintilla->SendScintilla(QsciScintilla::SCI_POINTXFROMPOSITION, 0, cursor_pos));
            point.setY(scintilla->SendScintilla(QsciScintilla::SCI_POINTYFROMPOSITION, 0, cursor_pos)
                + scintilla->SendScintilla(QsciScintilla::SCI_TEXTHEIGHT, 0) + 2);

            int count;
            count = VGlobal::input_tip->count()>10?10:VGlobal::input_tip->count();
            qDebug() << count;

            VGlobal::input_tip->move(scintilla->mapToGlobal(point));
            VGlobal::input_tip->setCurrentRow(0);

            VGlobal::input_tip->setMinimumWidth(VGlobal::input_tip->sizeHintForColumn(0) +
                2 * VGlobal::input_tip->frameWidth() + 35);
            VGlobal::input_tip->setMinimumHeight(VGlobal::input_tip->sizeHintForRow(0) * count
                + 2 * VGlobal::input_tip->frameWidth());
            VGlobal::input_tip->setMaximumHeight(VGlobal::input_tip->sizeHintForRow(0) * count
                + 2 * VGlobal::input_tip->frameWidth());

            // 设置位置大小
    //        VGlobal::input_tip->setGeometry(scintilla->mapToGlobal(point).x,
    //                                         scintilla->mapToGlobal(point).y,
    //                                         0, (VGlobal::input_tip->sizeHintForRow(0) *
    //                                         VGlobal::input_tip->count() + 2 *
    //                                         VGlobal::input_tip->frameWidth()));

            VGlobal::input_tip->show();
            if(scintilla->hasFocus() == false)
            {
                VGlobal::input_tip->hide();VGlobal::input_tip->hide();
            }
        }else
        {
            VGlobal::input_tip->hide();VGlobal::input_tip->hide();
        }
    }
    else
    {
        VGlobal::input_tip->hide();VGlobal::input_tip->hide();
    }
}

void MainWindow::slot_show_function_parameter_calltip(QString text, int pos)
{
    VGlobal::parameter_tip->setText(text);
    VGlobal::parameter_tip->adjustSize();

    auto scintilla = get_current_active_scintilla();
    //ui->tabwidget->get_current_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    QPoint point;
    point.setX(scintilla->SendScintilla(QsciScintilla::SCI_POINTXFROMPOSITION, 0, pos));
    point.setY(scintilla->SendScintilla(QsciScintilla::SCI_POINTYFROMPOSITION, 0, pos) -
        VGlobal::parameter_tip->height());
    VGlobal::parameter_tip->move(scintilla->mapToGlobal(point));
    VGlobal::parameter_tip->show();
}

void MainWindow::slot_show_mouse_hover_calltip(QString text, int pos)
{
    VGlobal::mouse_hover_tip->setText(text);
    VGlobal::mouse_hover_tip->adjustSize();

    auto scintilla = get_current_active_scintilla();
            //ui->tabwidget->get_current_scintilla();
    if(scintilla == nullptr)
    {
        VGlobal::mouse_hover_tip->hide();
        return;
    }

    // 如果菜单列表是可见的
    // 则中止显示
    if(scintilla->_content_menu.isVisible())
    {
        return;
    }

    QPoint point;
    point.setX(scintilla->SendScintilla(QsciScintilla::SCI_POINTXFROMPOSITION, 0, pos));
    point.setY(scintilla->SendScintilla(QsciScintilla::SCI_POINTYFROMPOSITION, 0, pos) +
        scintilla->textHeight(scintilla->posOfLine(pos))
        );

    VGlobal::mouse_hover_tip->move(scintilla->mapToGlobal(point));
    VGlobal::mouse_hover_tip->show();
}

void MainWindow::slot_jump(QString path, int line_number)
{
    line_number--;
    jump_to(path, line_number);
//    ui->tabwidget->open_file(path);
//    ui->tabwidget->jump(path, line_number);
}

void MainWindow::slot_show_build_information(QList<VErrorWidget::VTableItem> list)
{
    // _output_listwidget->clear();
    foreach (VErrorWidget::VTableItem item, list)
    {
        _error_widget->table_add_line_data(item);
    }
}

void MainWindow::slot_append_output_text(QString text)
{

    _output_widget->output_append(text);
//    _output_widget->output_append(text);
}

void MainWindow::slot_startpage_action(int type, QString text)
{
    if(type == VStartPage::SignalType::START)
    {
        if(text == "新建项目")
        {
            on_action_new_project_triggered();
        }
        else if(text == "打开项目")
        {
            on_action_open_project_triggered();
        }
    }
    else if(type == VStartPage::SignalType::HISTORICAL)
    {
       _project_treewidget->open_project(text);
    }
    else if(type == VStartPage::SignalType::INFORMATION)
    {

    }
}

void MainWindow::slot_change_symbol(QString text)
{

    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr) return;

    int cursor = scintilla->cursorPos();
    if(text == "." && scintilla->text(cursor-2, cursor) == "->")
    {
        scintilla->setSelect(cursor-2, cursor);
        scintilla->replaceSelectedText(text);
    }
    else if(text == "->" && scintilla->text(cursor-1, cursor) == ".")
    {
        scintilla->setSelect(cursor-1, cursor);
        scintilla->replaceSelectedText(text);
    }
}

void MainWindow::slot_save_file(QString path, QString text, int type, uint last)
{
    qDebug() << "save file " << path;

    // 更新到后台
    emit signal_update_file_text(path, text);
    // 更新时间
    emit signal_set_file_last_time(path, last);

    // type
}

void MainWindow::slot_open_file(QString path)
{
    open_file(path);


//    dock->show();
//    ui->tabwidget->open_file(path);
}

void MainWindow::slot_update_keywords(QString path, int type, QStringList list)
{

    //    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 0, (int)"inta");
    //    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 1, (int)"intb");
//        ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 3, list.join(' ').toStdString().data());
    //    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 5, 0x92bd6c);
    //    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 16, 0xc06a15);
    //        ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 19, 0x007acc);
}

void MainWindow::slot_rename(QString old_path, QString new_path)
{
    auto scintilla = get_scintilla(old_path);
    if(scintilla == nullptr) return;
    scintilla->rename(new_path);
    emit signal_rename(old_path, new_path);
}

void MainWindow::slot_update_file_text(QString path, QString text)
{
    qDebug() << "slot_update_file_text:" << path;
    emit signal_update_file_text(path, text);
}

void MainWindow::slot_update_file_last_modify_time(QString path, uint time)
{
//    qDebug() << "slot_update_file_last_modify_time:" << path;
    emit signal_update_file_last_modify_time(path, time);
}

void MainWindow::slot_reload_file(QString path)
{
//    qDebug() << "slot_reload_file:" << path;\
    emit signal_reload_file(path);
}

void MainWindow::slot_file_tip(QString path, QString text)
{
//    qDebug() << "slot_file_tip:" << path;
    emit signal_file_calltip(path, text);
}

void MainWindow::slot_input_tip(QString path, QString text, int line, bool in)
{
//    qDebug() << "slot_input_tip:" << path;
    emit signal_input_tip(path, text, line, in);
}

void MainWindow::slot_patameter_tip(QString path, QString name, int cursor_pos, int parameter_pos)
{
//    qDebug() << "slot_patameter_tip:" << path;
    emit signal_patameter_tip(path, name, cursor_pos, parameter_pos);
}

void MainWindow::slot_mouse_hover_tip(QString path, QString before, QString after, int line, bool in, int pos)
{
//    qDebug() << "slot_mouse_hover_tip:" << path;
    emit signal_mouse_hover_tip(path, before, after, line, in, pos);
}

void MainWindow::slot_hide_tip(int mode)
{
    if(mode & VGlobal::TipType::TIP_INPUT)
    {
        VGlobal::input_tip->hide();
    }
    if(mode & VGlobal::TipType::TIP_PARAMETER)
    {
        VGlobal::parameter_tip->hide();
    }
    if(mode & VGlobal::TipType::TIP_MOUSERHOVER)
    {
        VGlobal::mouse_hover_tip->hide();
    }
//    qDebug() << "slot hide tip:" << mode;
//    if(mode == "all")
//    {
//        VGlobal::input_tip->hide();
//        VGlobal::parameter_tip->hide();
//        VGlobal::mouse_hover_tip->hide();
//    }
//    else if(mode == "parameter")
//    {
//        VGlobal::parameter_tip->hide();
//    }
//    else if(mode == "input")
//    {
//        VGlobal::input_tip->hide();
//    }
//    else if(mode == "mouse hover")
//    {
//        VGlobal::mouse_hover_tip->hide();
//    }
//    qDebug() << "slot_hide_tip:" << mode;

}

void MainWindow::slot_open_project(QString path)
{
    emit signal_open_project(path);
}

void MainWindow::slot_select_word(QString path, VWords *word)
{
    emit signal_select_word(path, word);
}

void MainWindow::slot_jump_request(QString path, QString pre, QString next, int line_number, bool in_function)
{
    qDebug() << "slot_jump_request";
    emit signal_jump_request(path, pre, next, line_number, in_function);
}

void MainWindow::slot_input_word_transfer(VWords *word)
{
   auto scintilla = get_scintilla(_current_path);
   if(scintilla == nullptr) return;
   scintilla->input_word(word);
}

void MainWindow::slot_append_navigation(QString path, int line, int pos)
{
    qDebug() << "slot_append_navigation" << path << " " << line << " " << pos;
    append_navigation(path, line, pos);
}

void MainWindow::slot_scintilla_update_info(QString path, int line, int pos, int lines)
{
    if(lines == -1 && path == _current_path)
    {
        this->setWindowTitle("易深编程" + VGlobal::version);
        _line_label->hide();
        _column_label->hide();
        _sum_line_label->hide();
        return;
    }

    _current_path = path;
    this->setWindowTitle("易深编程" + VGlobal::version + "  " + path);

    _line_label->show();
    _line_label->setText(QString("行:%1").arg(line));
    _column_label->show();
    _column_label->setText(QString("列:%1").arg(pos));
    _sum_line_label->show();
    _sum_line_label->setText(QString("总行数:%1").arg(lines));
}

void MainWindow::slot_find(const QString &expr, bool re, bool cs, bool wo, bool wrap, bool forward, int line, int index, bool show, bool posix, bool cxx11, QString rexpr, bool replace, bool replace_all)
{
    int result;
    auto scintilla = get_scintilla(_current_path);
    if(scintilla == nullptr) return;

    if(replace == false
            && replace_all == false)
    {
        result = scintilla->findFirst(expr, re, cs, wo, wrap, forward, line, index, show, posix, cxx11);
        if(result == false)
        {
            emit signal_set_title("提示：没有找到下一个", 3000);
            return;
        }
    }

    if(replace)
    {
        int pos;
        int cursor = scintilla->cursorPos();
        int anchor = scintilla->anchorPos();
        if(cursor < anchor)
            pos = cursor;
        else
            pos = anchor;
        scintilla->setSelect(pos, pos);
        result = scintilla->findFirst(expr, re, cs, wo, wrap, forward, line, index, show, posix, cxx11);
        if(result == false)
        {
            emit signal_set_title("提示：没有找到下一个", 3000);
            return;
        }

        if(cxx11)
        {
            QString select_text = scintilla->selectedText();
            QString replace_text = select_text.replace(QRegularExpression(expr), rexpr);
            scintilla->replaceSelectedText(replace_text);
        }
        else
        {
            scintilla->replaceSelectedText(rexpr);
        }
        result = scintilla->findFirst(expr, re, cs, wo, wrap, forward, line, index, show, posix, cxx11);
        if(result)
        {
            emit signal_set_title("提示 : 替换完成, 并且找到下一个", 3000);
            return;
        }
    }

    if(replace_all)
    {
        wrap = false;       // 关闭循环查找
        forward = true;    // 关闭逆向查找
        scintilla->setSelect(0, 0);
        int n=0;
        do{
            result = scintilla->findFirst(expr, re, cs, wo, wrap, forward, line, index, show, posix, cxx11);
            if(result == false)
            {
                emit signal_set_title(QString("提示 : 替换%1个").arg(n), 3000);
                return;
            }

            if(cxx11)
            {
                QString select_text = scintilla->selectedText();
                QString replace_text = select_text.replace(QRegularExpression(expr), rexpr);
                scintilla->replaceSelectedText(replace_text);
            }
            else
            {
                scintilla->replaceSelectedText(rexpr);
            }
            n++;
        }while(result);
    }
}

void MainWindow::append_navigation(QString path, int line, int pos)
{
    // 判断路径是否存在
    // 不存在则返回
    if(path.length() == 0)
    {
        return;
    }

    // 判断 index 是否在中途
    // 如果在中途则清楚后面的内容
    int count = _navigation_list.count() - 1 - _navigation_index;
    if(count > 0)
    {
        while(count -- )
        {
            _navigation_list.removeAt(_navigation_index + 1);
        }
    }

    // 判断是否和上一个的内容相同
    // 如果相同则清楚当前条
    // 确保最新信息
    if(_navigation_list.count() > 0)
    {
        if(_navigation_list.at(_navigation_index).line == line
                && _navigation_list.at(_navigation_index).path == path)
        {
             _navigation_list.removeAt(_navigation_index);
        }
    }


    NavigationInfo nav;
    nav.line = line;
    nav.path = path;
    nav.pos = pos;
    _navigation_list.append(nav);
    _navigation_index = _navigation_list.count() - 1;
}

bool MainWindow::apped_historical_record(QString path)
{
    // 统一符号
    path = path.replace("\\", "/");

    QString text = VFunctions::read_file_text(VGlobal::historical_record_path);
    text = text.replace(path+"\r\n", "");
    text = path + "\r\n" + text;
    VFunctions::save_file(VGlobal::historical_record_path, text);

    // reload
    _startpage_widget->load_historical();
}

void MainWindow::init_qss()
{
    QString text = VFunctions::read_file_text(VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/index.qss");
    QString icon_dir = VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon";
    this->setStyleSheet(text.replace("<IconDir>", icon_dir));
}

// 前进
void MainWindow::on_action_advance_triggered()
{

    if(_navigation_index < _navigation_list.count() - 1)
    {
        _navigation_index++;
//        ui->tabwidget->open_file(_navigation_list.at(_navigation_index).path);
//        qDebug() << _navigation_list.at(_navigation_index).path;
        jump_to(_navigation_list.at(_navigation_index).path,
                            _navigation_list.at(_navigation_index).line,
                            _navigation_list.at(_navigation_index).pos,
                            false);
    }

}

// 后退
void MainWindow::on_action_retreat_triggered()
{
    if(_navigation_index > 0)
    {
        _navigation_index--;
//        ui->tabwidget->open_file(_navigation_list.at(_navigation_index).path);
        jump_to(_navigation_list.at(_navigation_index).path,
                            _navigation_list.at(_navigation_index).line,
                            _navigation_list.at(_navigation_index).pos,
                            false);
    }
}

void MainWindow::on_action_new_project_triggered()
{
    VNewProjectDialog *w;
    w = new VNewProjectDialog(this);
    int result = w->exec();

    // 判断是否取消创建
    if(result == QDialog::Rejected)
    {
        return;
    }

    QString dir = w->_dir;
    QString project_name = w->_name;
    QString crystal = w->_jz;
    QString model = w->_type;
    QString brand = w->_brand;
    QString esln_path = dir + "/" + project_name + "/" + project_name + ".esln";
    QString source_dir = dir + "/" + project_name;

    // 创建文件夹
    VFunctions::creat_dir(dir, project_name);

    // 写入配置
    QString index_json_path = VGlobal::config_dir+"/project/" + brand + "/" + model + "/index.json";
    QString index_json_text = VFunctions::read_file_text(index_json_path);

    index_json_text = index_json_text.replace("$(ProjectName)", project_name);
    index_json_text = index_json_text.replace("$(brand)", brand);
    index_json_text = index_json_text.replace("$(model)", model);
    index_json_text = index_json_text.replace("$(crystal)", crystal);

    VFunctions::save_file(esln_path, index_json_text);
    // json
//    QJsonParseError json_error;
//    QJsonDocument json_document = QJsonDocument::fromJson(index_json_text.toUtf8(), &json_error);
//    if(json_error.error != QJsonParseError::NoError)
//    {
//        QMessageBox::critical(this, "错误", index_json_path + " 解析失败");
//        return ;
//    }

//    QJsonObject json_obj;
//    json_obj = json_document.object();
//    json_obj.insert("crystal", crystal);
//    json_obj.insert("mcu_type", mcu_type);
//    json_obj.insert("brand", brand);
//    json_obj.insert("solution", project_name);

//    json_document.setObject(json_obj);
//    VFunctions::save_file(esln_path, json_document.toJson());

    // 文件复制
    // 遍历file文件
    QStringList path_list = VFunctions::get_file_path_list
            (VGlobal::config_dir+"/project/" + brand + "/" + model + "/file");

    foreach(QString path, path_list)
    {
        QString file_name = QFileInfo(path).fileName();
        QFile::copy(path, source_dir + "/" + file_name);
    }


  _project_treewidget->open_project(esln_path);
}

void MainWindow::on_action_open_project_triggered()
{
    QString file_full_path = QFileDialog::getOpenFileName(this, "打开工程", "", "esln(*.esln)");
    if (file_full_path.isEmpty())
    {
        return;
    }

   _project_treewidget->open_project(file_full_path);
}

void MainWindow::on_action_close_file_triggered()
{
    auto dock = get_scintilla_dockwidget(_current_path);
    if(dock == nullptr) return;

    auto scintilla = (VScintillaEx*)(dock->widget());
    if(scintilla->_modify)
    {
        bool result = scintilla->save_question();
        if(result == false)
        {
            return;
        }
    }

    dock->setParent(nullptr);
    QMainWindow::removeDockWidget(dock);
    _dockwidget_list.removeOne(dock);
}

void MainWindow::on_action_save_triggered()
{
    VScintillaEx* scintilla = get_current_active_scintilla();
    if(scintilla != nullptr) scintilla->save();
//    ui->tabwidget->save();
//    if(_open_tabbar->count() == 0)
//    {
//        return;
//    }

//    int index = _open_tabbar->currentIndex();
//    auto data = get_tab_data(index);
//    if(data->_type == VGlobal::TabType::SCINTILLA
//            && data->_scintilla_data._modify)
//    {
//        // 清除标题的 *
//        QString text = _open_tabbar->tabText(index);
//        _open_tabbar->setTabText(index, text.replace("*", ""));

//        VFunctions::save_file(data->_path, _text_edit->text());
//        data->_scintilla_data._last_modify_time = VFunctions::file_last_modify_time(_current_path);
//        data->_scintilla_data._modify = false;
//        _text_edit->setModified(false);

//        save_file_processor(data->_scintilla_data._doc_type);

//        // 更新到后台
//        emit signal_update_file_text(data->_path, get_document_text(data->_scintilla_data._document));
//        // 更新时间
//        emit signal_set_file_last_time(data->_path, data->_scintilla_data._last_modify_time);
//    }
}

void MainWindow::on_action_save_all_triggered()
{
    foreach(VDockWidget* dock, _dockwidget_list)
    {
        auto scintilla = (VScintillaEx*)(dock->widget());
        if(scintilla->_modify)
            scintilla->save();
    }

//    ui->tabwidget->save_all();
//    for (int i = 0; i < _open_tabbar->count(); i++)
//    {
//        auto data = get_tab_data(i);
//        if(data->_type == VGlobal::TabType::SCINTILLA)
//        {
//            if(data->_scintilla_data._modify)
//            {
//                // 删除 *
//                QString text = _open_tabbar->tabText(i);
//                _open_tabbar->setTabText(i, text.replace("*", ""));

//                text = get_document_text(data->_scintilla_data._document);
//                VFunctions::save_file(data->_path, text);
//                data->_scintilla_data._last_modify_time = VFunctions::file_last_modify_time(data->_path);
//                data->_scintilla_data._modify = false;

//                if(data->_path == _current_path)
//                {
//                    _text_edit->setModified(false);
//                }

//                // 保存处理
//                save_file_processor(data->_scintilla_data._doc_type);

//                // 更新到后台
//                emit signal_update_file_text(data->_path, get_document_text(data->_scintilla_data._document));
//                // 更新时间
//                emit signal_set_file_last_time(data->_path, data->_scintilla_data._last_modify_time);
//            }
//        }
//    }
}

void MainWindow::on_action_exit_triggered()
{
    this->close();
}

void MainWindow::on_action_undo_triggered()
{
    auto scintilla = get_current_active_scintilla();
    //ui->tabwidget->get_current_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }
    scintilla->undo();
}

void MainWindow::on_action_redo_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }
    scintilla->redo();
}

void MainWindow::on_action_cut_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }
    scintilla->cut();
}

void MainWindow::on_action_copy_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->copy();
//    if(_output_listwidget->hasFocus())
//    {
//        auto item = _output_listwidget->currentItem();
//        if(item != nullptr)
//        {
//            QApplication::clipboard()->setText(item->text());
//        }
//    }
//    else
//    {
//        _text_edit->copy();
//    }
}

void MainWindow::on_action_paste_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }
    scintilla->paste();
}

void MainWindow::on_action_comment_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }
    scintilla->copy();

    int cursor_of_line = scintilla->cursorOfLine();
    int anchor_of_line = scintilla->anchorOfLine();
    int start_line = 0;
    int end_line = 0;
    if (cursor_of_line > anchor_of_line)
    {
        start_line = anchor_of_line;
        end_line = cursor_of_line;
    }
    else
    {
        start_line = cursor_of_line;
        end_line = anchor_of_line;
    }

    for (auto i = start_line; i <= end_line; i++)
    {
        int indent = scintilla->indentation(i);
        int line_start_pos = scintilla->lineStartPos(i);
        scintilla->insertText(line_start_pos + indent / scintilla->tabWidth(), "//");
    }

    if (start_line != end_line)
    {
        int start_pos = scintilla->lineStartPos(start_line);
        int end_pos = scintilla->lineEndPos(end_line);
        scintilla->setSelectStartPos(start_pos);
        scintilla->setSelectEndPos(end_pos);
    }
}

void MainWindow::on_action_uncomment_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    int cursor_of_line = scintilla->cursorOfLine();
    int anchor_of_line = scintilla->anchorOfLine();
    int start_line = 0;
    int end_line = 0;
    if (cursor_of_line > anchor_of_line)
    {
        start_line = anchor_of_line;
        end_line = cursor_of_line;
    }
    else
    {
        start_line = cursor_of_line;
        end_line = anchor_of_line;
    }

    for (auto i = start_line; i <= end_line; i++)
    {
        QString s = scintilla->text(i);
        int pos = s.indexOf("//");
        if (pos != -1)
        {
            int line_start_pos = scintilla->lineStartPos(i);
            scintilla->deleteRange(line_start_pos + pos, 2);
        }
    }
}

void MainWindow::on_action_left_ident_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->backTab();
}

void MainWindow::on_action_right_ident_triggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->Tab();
}

void MainWindow::on_action_biulder_triggered()
{

//    VSettingDialog dlg(this);
//    dlg.exec();
//    return;

//    QJsonObject parent;
//    QJsonArray array;

//    for(int i=0; i<=249; i++)
//    {
//        QString type;
//        switch (ErrNamespace::ErrTab[i].errType)
//        {
//        case ErrNamespace::ERROR_LEVEL_ERROR:
//        case ErrNamespace::ERROR_LEVEL_SYNTAX_ERROR:
//            type = "error";
//            break;
//        case ErrNamespace::ERROR_LEVEL_PEDANTIC:
//        case ErrNamespace::ERROR_LEVEL_WARNING:
//            type = "warning";
//            break;
//        case ErrNamespace::ERROR_LEVEL_INFO:
//            type = "info";
//            break;
//        }

//        int index = ErrNamespace::ErrTab[i].errIndex;

//        QString source = ".*?"+ErrNamespace::ErrTab[i].errText;
//        QString replace = ErrNamespace::ErrTab[i].cn_errText;
//        replace = replace.replace("%", "\\");

//        QJsonObject object;
//        object.insert("number", QJsonValue(index));
//        object.insert("type", QJsonValue(type));
//        object.insert("source", QJsonValue(source));
//        object.insert("replace", QJsonValue(replace));
//        array.append(QJsonValue(object));
//    }

//    parent.insert("errors", QJsonValue(array));

//    VFunctions::save_file("d:/1.josn", QJsonDocument(parent).toJson());



//    return;
    foreach(VDockWidget* dock, _dockwidget_list)
    {
        auto scintilla = (VScintillaEx*)(dock->widget());
        scintilla->modify_testing();
    }

    build_project(_project_treewidget->_active_project);
}

void MainWindow::on_action_delete_triggered()
{

}

void MainWindow::on_action_close_project_triggered()
{
   _project_treewidget->close_project();

    auto item =_project_treewidget->currentItem();
    QString esln_path =_project_treewidget->get_project_esln_path(item);
    QStringList modify_file_paths;
    QStringList open_file_paths;
    foreach(QString path, VFunctions::get_project_all_file_path(esln_path))
    {
        auto scintilla = get_scintilla(path);
        if(scintilla != nullptr)
        {
            open_file_paths.append(path);
            if(scintilla->_modify)
            {
                modify_file_paths.append(path);
            }
        }
    }

    VSaveQuestion dlg(this, modify_file_paths);
    int result = QDialog::Accepted;
    if(modify_file_paths.count() > 0)
    {
        result = dlg.exec();
    }

    if(result == QDialog::Accepted)
    {
        foreach(QString path, dlg._save_paths)
        {
            auto scintilla = get_scintilla(path);
            if(scintilla != nullptr)
            {
                scintilla->save();
                slot_scintilla_update_info(scintilla->_path, -1, -1, -1);
            }
        }

        foreach(QString path, open_file_paths)
        {
            auto dock = get_scintilla_dockwidget(path);
            if(dock != nullptr)
            {
                dock->setParent(nullptr);
                QMainWindow::removeDockWidget(dock);
                _dockwidget_list.removeOne(dock);
            }
        }

       _project_treewidget->remove_project(item);
        emit signal_close_projct(esln_path);
    }

    // 检测 file_list 中的文件是否打开了
    // 如果打开看是否修改
    // 否则直接关闭
    // 全部关闭后 关闭项目


//    if(ui->tabwidget->close_file(path_list))
//    {
//       _project_treewidget->remove_project(item);
//        emit signal_close_projct(esln_path);
//    }

    // 移除项目
//    auto root = _project_treewidget->invisibleRootItem();
//    root->removeChild(item);

//    // 判断关闭的是不是活动项目
//    if(esln_path == _active_project_path)
//    {
//        _active_project_path = "";
//        if(root->childCount() > 0)
//        {
//            // 设置第一个为活动项目
//            QString path = get_project_esln_path(root->child(0));
//            set_active_project(path);
//        }
//    }
}

void MainWindow::on_action_search_triggered()
{
    _search_dock->show();
}

void MainWindow::on_action_new_file()
{
//   _project_treewidget->slot_new_file();
}

void MainWindow::on_action_get_more()
{
    QDesktopServices::openUrl(QString("https://www.51yishen.com"));
}

void MainWindow::on_action_rename()
{

}

// 导出模块
void MainWindow::on_action_export_file()
{
   _project_treewidget->export_file();
}

void MainWindow::on_action_open_to_dir()
{
    QString path = _project_treewidget->get_current_project_path();
    QString project_dir = QFileInfo(path).path();
    QDesktopServices::openUrl(QUrl::fromLocalFile(project_dir));
}

void MainWindow::on_action_access_file_homepage()
{
   _project_treewidget->access_file_homepage();
//    if(_project_treewidget->isActiveWindow())
//    {
//        auto current_item = _project_treewidget->currentItem();
//        auto item_data = VProjectTreeWidget::get_item_data(current_item);

//        if(item_data.type == VProjectTreeWidget::TreeWidgetItemType::FILE)
//        {
//            QString document = get_file_text(item_data.path);

//            QRegularExpression reg;
//            reg.setPattern("//主页\\s*(.+)");
////            reg.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
//            QRegularExpressionMatch match;
//            match = reg.match(document);
//            if(match.hasMatch())
//            {
//                qDebug() << match.captured(1);
//                QString url = match.captured(1).replace("\r","");
//                QDesktopServices::openUrl(url);
//            }
//            else
//            {
//                QMessageBox::information(this, "访问文件主页", "该文件没有主页信息");
//            }
//        }

//    }
}

void MainWindow::on_action_access_project_homepage()
{
   _project_treewidget->access_file_homepage();
//    auto item = _project_treewidget->currentItem();
//    if(item != nullptr)
//    {
//        QString esln_path = VProjectTreeWidget::get_project_esln_path(item);
//        QJsonObject object = VFunctions::get_file_jsonDocument(esln_path).object();
//        QString url = object.value("homepage").toString();
//        if(url.isEmpty() == false)
//        {
//            QDesktopServices::openUrl(url);
//        }
//        else
//        {
//            QMessageBox::information(this, "访问项目主页", "该项目没有主页信息");
//        }
//    }

}

void MainWindow::on_action_project_pack()
{
   _project_treewidget->on_project_pack();
}

void MainWindow::on_action_code_format()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    QString text = scintilla->selectedText();
    if(text.length() == 0)
    {
        // 没有选中文本, 全文排版

        // 备份cursorpos, anchorpos, firstVisbelLine

        int cursor_pos = scintilla->cursorPos();
        int first_visble_line = scintilla->firstVisibleLine();

        text = scintilla->text();
        text = VFunctions::indent(VGlobal::setting.code_format, text);
        scintilla->selectAll();
        scintilla->replaceSelectedText(text);

        scintilla->setSelect(cursor_pos, cursor_pos);
        scintilla->setFirstVisibleLine(first_visble_line);
    }
    else
    {
        // 选中文本, 部分排版
        text = VFunctions::indent(VGlobal::setting.code_format, text);
        scintilla->replaceSelectedText(text);
    }
}

void MainWindow::on_action_project_attribute()
{
   _project_treewidget->on_project_attribute();
//   _project_treewidget->slot_project_attribute();
}

void MainWindow::on_action_startpage_trggered()
{
    _startpage_dock->setVisible(true);
    _startpage_dock->raise();
//    open_to_display(_startpage_widget, "起始页");
}

void MainWindow::on_action_project_build_trggered()
{
    QString path =_project_treewidget->get_current_project_path();
    build_project(path);
}

void MainWindow::on_action_jump_trggered()
{
    qDebug() << "on_action_jump_trggered";
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->jump_request();

//    if(_output_listwidget->hasFocus())
//    {
//        // 进行跳转

//        VOutputQListWidgetItemData * data = get_listwidget_item_data(_output_listwidget->currentItem());
//        qDebug() << data;
//        if(data != nullptr && data->_path.isEmpty() == false
//                && data->_line != -1)
//        {
//            qDebug() << data->_path;
//            goto_file_pos(data->_path, data->_line-1);
//        }
//        _text_edit->setFocus();
//    }
//    else
//    {
//        QString pre = get_line_text_of_pos_before(_text_edit->cursorPos());
//        QString next = get_line_text_of_pos_next(_text_edit->cursorPos());
//        bool in_function = _text_edit->lineFoldLevel(_text_edit->cursorOfLine())>1024;
//        emit signal_jump(pre, next, _text_edit->posOfLine(_text_edit->cursorPos()) + 1, in_function);


//    }
}

void MainWindow::on_action_foldAll_trggered()
{
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 0, (int)"inta");
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 1, (int)"intb");
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_SETKEYWORDS, 3, "aabbcc");
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 5, 0x92bd6c);
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 16, 0xc06a15);
//    ui->tabwidget->get_current_scintilla()->SendScintilla(QsciScintilla::SCI_STYLESETFORE, 19, 0x007acc);
//    return;
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->SendScintilla(QsciScintilla::SCI_FOLDALL, QsciScintilla::SC_FOLDACTION_CONTRACT);
}

void MainWindow::on_action_expandedAll_trggered()
{
    auto scintilla = get_current_active_scintilla();
    if(scintilla == nullptr)
    {
        return;
    }

    scintilla->SendScintilla(QsciScintilla::SCI_FOLDALL, QsciScintilla::SC_FOLDACTION_EXPAND);
}

void MainWindow::on_action_search_pre_trggered()
{
}

void MainWindow::on_action_search_next_trggered()
{
}

void MainWindow::on_action_search_replace_trggered()
{
}

void MainWindow::on_action_search_replace_all_trggered()
{
}

void MainWindow::on_action_questions_trggered()
{
    QDesktopServices::openUrl(QString("https://www.51yishen.com"));
}

void MainWindow::on_source_content_trggered()
{
    if(QFile(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt").exists())
    {

        QDesktopServices::openUrl(QUrl::fromLocalFile(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt"));
//        if(open_tabbar_contain(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt"))
//        {
//            auto data = get_tab_data(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt");
//            set_document_text(data->_scintilla_data._document, VFunctions::read_file_text(
//                                  VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt"));
//        }
//        else
//        {
//            open_to_display(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt");
//        }
    }
}

void MainWindow::on_action_setting_trggered()
{
    VSettingDialog dlg(this);
    int result = dlg.exec();
    if(result == QDialog::Accepted)
    {
        VFunctions::load_setting();
        init_action_shortCut();

        // scintilla
        foreach(VDockWidget *dock, _dockwidget_list)
        {
            auto scintilla = (VScintillaEx*)(dock->widget());
            scintilla->reload_setting();
        }
    }
}

void MainWindow::init()
{
}

void MainWindow::init_ui()
{
    init_title();
    init_call_tip_widget();
    init_main_toolbar();
    init_menubar();
    init_tool_menu();
    init_content_menu();
    init_append_menu();
    init_statuebar();
    init_project_dock();
    init_output_dock();
    init_error_dock();
    init_search_dock();
//    init_outline_dock();
    init_startpage_widget();
}

void MainWindow::init_project_dock()
{
    _project_treewidget = new VProjectTreeWidget(this);
    _project_treewidget->setHeaderHidden(true);
    _project_treewidget->setDragDropMode(QAbstractItemView::InternalMove);
    _project_treewidget->init();

    _project_dock = new VDockWidget("工程项目", VDockWidget::CloseType::HIDE);
    _project_dock->setWidget(_project_treewidget);
    _project_dock->setObjectName("project_dock");
    _project_dock->setWindowTitle("工程项目");
    QMainWindow::addDockWidget(Qt::LeftDockWidgetArea, _project_dock);
    QObject::connect(_project_treewidget, &VProjectTreeWidget::signal_reload_project, _background_system, &VBackgroundSystem::slot_reload_project);
    QObject::connect(_project_treewidget, &VProjectTreeWidget::signal_rename, this, &MainWindow::slot_rename);
    QObject::connect(_project_treewidget, &VProjectTreeWidget::signal_open_file, this, &MainWindow::slot_open_file);
    QObject::connect(_project_treewidget, &VProjectTreeWidget::signal_open_project, this, &MainWindow::slot_open_project);
    QObject::connect(_project_treewidget, &VProjectTreeWidget::signal_jump, this, &MainWindow::slot_jump);
    QObject::connect(_background_system, &VBackgroundSystem::signal_update_outline, _project_treewidget, &VProjectTreeWidget::slot_update_outline);
    QObject::connect(_background_system, &VBackgroundSystem::signal_append_external_dependence, _project_treewidget, &VProjectTreeWidget::slot_append_external_dependence);
}

void MainWindow::init_title()
{
    // 设置title
    this->setWindowTitle("易深编程" + VGlobal::version);
}

void MainWindow::init_call_tip_widget()
{
    VGlobal::input_tip = new VInputListWidget();
    VGlobal::input_tip->setParent(0, Qt::Popup);
    VGlobal::input_tip->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::SubWindow | Qt::Popup);
    VGlobal::input_tip->setAttribute(Qt::WA_ShowWithoutActivating, true);
    VGlobal::input_tip->setStyleSheet(this->styleSheet());
    VGlobal::input_tip->setFont(this->font());
    VGlobal::input_tip->hide();


    VGlobal::parameter_tip = new QLabel();
    VGlobal::parameter_tip->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::SubWindow | Qt::Popup);
    VGlobal::parameter_tip->setAttribute(Qt::WA_ShowWithoutActivating, true);
    VGlobal::parameter_tip->setObjectName("parameter_calltip_label");
    VGlobal::parameter_tip->setStyleSheet(this->styleSheet());
    VGlobal::parameter_tip->hide();
    VGlobal::parameter_tip->setFont(this->font());

    VGlobal::mouse_hover_tip = new QLabel();
    VGlobal::mouse_hover_tip->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::SubWindow | Qt::Popup);
    VGlobal::mouse_hover_tip->setAttribute(Qt::WA_ShowWithoutActivating, true);
    VGlobal::mouse_hover_tip->setObjectName("mouse_hover_calltip_label");
    VGlobal::mouse_hover_tip->setStyleSheet(this->styleSheet());
    VGlobal::mouse_hover_tip->setFont(this->font());
    VGlobal::mouse_hover_tip->hide();

    QObject::connect(VGlobal::input_tip, &VInputListWidget::signal_input_word, this, &MainWindow::slot_input_word_transfer);
}

void MainWindow::init_background_system()
{
    _background_thread = new QThread();
    _background_system = new VBackgroundSystem();
    _background_system->moveToThread(_background_thread);

    // 注册自定义数据类型
    qRegisterMetaType<QList<VWords*>>("QList<VWords*>");
    qRegisterMetaType<QList<QTreeWidgetItem*>>("QList<QTreeWidgetItem*>");
    qRegisterMetaType<QList<VErrorWidget::VTableItem*>>("QList<VErrorWidget::VTableItem>");

    // 信号和槽的连接
//    QObject::connect(this, &MainWindow::signal_set_now_path, _background_system, &VBackgroundSystem::slot_set_now_path);
//    QObject::connect(this, &MainWindow::signal_update_file_text, _background_system, &VBackgroundSystem::slot_update_file_data);
    QObject::connect(this, &MainWindow::signal_input_tip, _background_system, &VBackgroundSystem::slot_input_tip);
    QObject::connect(this, &MainWindow::signal_patameter_tip, _background_system, &VBackgroundSystem::slot_parameter_calltip);
    QObject::connect(this, &MainWindow::signal_mouse_hover_tip, _background_system, &VBackgroundSystem::slot_mouse_hover_calltip);
    QObject::connect(this, &MainWindow::signal_jump_request, _background_system, &VBackgroundSystem::slot_jump_request);
    QObject::connect(this, &MainWindow::signal_build, _background_system, &VBackgroundSystem::slot_build);
    QObject::connect(this, &MainWindow::signal_set_file_last_time, _background_system, &VBackgroundSystem::slot_set_file_last_time);
    QObject::connect(this, &MainWindow::signal_reload_testing, _background_system, &VBackgroundSystem::slot_reload_testing);
    QObject::connect(this, &MainWindow::signal_file_calltip, _background_system, &VBackgroundSystem::slot_file_calltip);
    QObject::connect(this, &MainWindow::signal_reload_file, _background_system, &VBackgroundSystem::slot_reload_file);
    QObject::connect(this, &MainWindow::signal_rename, _background_system, &VBackgroundSystem::slot_rename);
    QObject::connect(this, &MainWindow::signal_select_word, _background_system, &VBackgroundSystem::slot_select_word);
    QObject::connect(this, &MainWindow::signal_open_project, _background_system, &VBackgroundSystem::slot_open_project);
    QObject::connect(this, &MainWindow::signal_close_projct, _background_system, &VBackgroundSystem::slot_close_project);

    QObject::connect(_background_system, &VBackgroundSystem::signals_calltip, this, &MainWindow::slot_show_input_calltip);
    QObject::connect(_background_system, &VBackgroundSystem::signals_parameter_calltip, this, &MainWindow::slot_show_function_parameter_calltip);
    QObject::connect(_background_system, &VBackgroundSystem::signal_mouse_hover_calltip, this, &MainWindow::slot_show_mouse_hover_calltip);
    QObject::connect(_background_system, &VBackgroundSystem::signal_jump, this, &MainWindow::slot_jump);
    QObject::connect(_background_system, &VBackgroundSystem::signal_show_build_information, this, &MainWindow::slot_show_build_information);
    QObject::connect(_background_system, &VBackgroundSystem::signal_change_symbol, this, &MainWindow::slot_change_symbol);
    QObject::connect(_background_system, &VBackgroundSystem::signal_update_keywords, this, &MainWindow::slot_update_keywords);
    QObject::connect(_background_system, &VBackgroundSystem::signal_append_output_text, this, &MainWindow::slot_append_output_text);
    _background_thread->start();
}

void MainWindow::init_startpage_widget()
{
    _startpage_widget = new VStartPage(this);
//    _startpage_widget->setObjectName("VStartPage");
    _startpage_widget->setFont(this->font());

    _startpage_widget->load_start();
    _startpage_widget->load_historical();
    _startpage_widget->load_information();

    QObject::connect(_startpage_widget, &VStartPage::signal_startpage_action, this, &MainWindow::slot_startpage_action);

    _startpage_dock = new VDockWidget("起始页", VDockWidget::CloseType::HIDE);
    _startpage_dock->setWidget(_startpage_widget);
    _startpage_dock->setObjectName("start");
//    this->setCentralWidget(dock);

//    QSizePolicy policy = dock->sizePolicy();
//    policy.setHorizontalStretch(5);
//    policy.setVerticalStretch(5);
//    policy.setHorizontalPolicy(QSizePolicy::Expanding);

//    dock->setSizePolicy(policy);
//    this->resize
//    qDebug() << "11111111111111111111" << dock->parent();
//dock->setWindowTitle(;
    QMainWindow::addDockWidget(Qt::BottomDockWidgetArea, _startpage_dock);
}

void MainWindow::init_icon_path()
{
    VGlobal::icon_path.insert("file_open", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/file_open.png");
    VGlobal::icon_path.insert("new_project", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/new_project.png");
    VGlobal::icon_path.insert("copy", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/copy.png");
    VGlobal::icon_path.insert("close_project", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/close_project.png");
    VGlobal::icon_path.insert("close_file", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/close_file.png");
    VGlobal::icon_path.insert("save_all", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/save_all.png");
    VGlobal::icon_path.insert("save", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/save.png");
    VGlobal::icon_path.insert("exit", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/exit.png");
    VGlobal::icon_path.insert("undo", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/undo.png");
    VGlobal::icon_path.insert("redo", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/redo.png");
    VGlobal::icon_path.insert("cut", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/cut.png");
    VGlobal::icon_path.insert("paste", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/paste.png");
    VGlobal::icon_path.insert("comment", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/comment.png");
    VGlobal::icon_path.insert("uncomment", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/uncomment.png");
    VGlobal::icon_path.insert("left_indent", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/left_indent.png");
    VGlobal::icon_path.insert("right_indent", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/right_indent.png");
    VGlobal::icon_path.insert("builder", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/builder.png");
    VGlobal::icon_path.insert("new_file", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/new-module.png");
    VGlobal::icon_path.insert("add_file", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/add-module.png");
    VGlobal::icon_path.insert("help", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/help.png");
    VGlobal::icon_path.insert("export", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/export.png");
    VGlobal::icon_path.insert("delete", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/delete.png");
    VGlobal::icon_path.insert("access_webpage", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/access_webpage.png");
    VGlobal::icon_path.insert("rename", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/rename.png");
    VGlobal::icon_path.insert("open_to_dir", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/open_to_dir.png");
    VGlobal::icon_path.insert("setting", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/setting.png");
    VGlobal::icon_path.insert("search", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/search.png");
    VGlobal::icon_path.insert("pack", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/pack.png");
    VGlobal::icon_path.insert("code_format", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/code_format.png");
    VGlobal::icon_path.insert("project_attribute", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/project-attribute.png");
    VGlobal::icon_path.insert("advance", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/advance.png");
    VGlobal::icon_path.insert("retreat", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/retreat.png");
    VGlobal::icon_path.insert("info", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/info.png");
    VGlobal::icon_path.insert("error", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/error.png");
    VGlobal::icon_path.insert("warning", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/warning.png");
    VGlobal::icon_path.insert("function", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/function.png");
    VGlobal::icon_path.insert("parameter", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/parameter.png");
    VGlobal::icon_path.insert("local", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/local.png");
    VGlobal::icon_path.insert("global", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/global.png");
    VGlobal::icon_path.insert("keyword", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/keyword.png");
    VGlobal::icon_path.insert("define", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/define.png");
    VGlobal::icon_path.insert("success", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/success.png");
    VGlobal::icon_path.insert("folder", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/folder.png");
    VGlobal::icon_path.insert("module", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/module.png");
    VGlobal::icon_path.insert("run_file", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/run_file.png");
    VGlobal::icon_path.insert("project", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/project.png");
    VGlobal::icon_path.insert("startpage", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/startpage.png");
    VGlobal::icon_path.insert("logo16", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/logo16.png");
    VGlobal::icon_path.insert("new_folder", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/new_folder.png");
    VGlobal::icon_path.insert("append", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/append.png");
    VGlobal::icon_path.insert("file_c", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/file_c.png");
    VGlobal::icon_path.insert("file_h", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/file_h.png");
    VGlobal::icon_path.insert("file_img", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/file_img.png");
    VGlobal::icon_path.insert("file_other", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/file_other.png");
    VGlobal::icon_path.insert("color", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/color.png");
    VGlobal::icon_path.insert("environment", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/environment.png");
    VGlobal::icon_path.insert("skin", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/skin.png");
    VGlobal::icon_path.insert("textedit", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/textedit.png");
    VGlobal::icon_path.insert("calltip", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/calltip.png");
    VGlobal::icon_path.insert("behavior", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/behavior.png");
    VGlobal::icon_path.insert("shortcut", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/shortcut.png");
    VGlobal::icon_path.insert("fold", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/fold.png");
    VGlobal::icon_path.insert("expanded", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/expanded.png");
    VGlobal::icon_path.insert("jump", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/jump.png");
    VGlobal::icon_path.insert("search_pre", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/search_pre.png");
    VGlobal::icon_path.insert("search_next", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/search_next.png");
    VGlobal::icon_path.insert("search_replace", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/search_replace.png");
    VGlobal::icon_path.insert("search_replace_all", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/search_replace_all.png");
    VGlobal::icon_path.insert("message", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/message.png");
    VGlobal::icon_path.insert("content", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/content.png");
    VGlobal::icon_path.insert("tool", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/tool.png");
    VGlobal::icon_path.insert("exe", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/exe.png");
    VGlobal::icon_path.insert("struct", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/struct.png");
    VGlobal::icon_path.insert("union", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/union.png");
    VGlobal::icon_path.insert("enumerator", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/enumerator.png");
    VGlobal::icon_path.insert("enum", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/enum.png");
    VGlobal::icon_path.insert("typedef", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/typedef.png");
    VGlobal::icon_path.insert("menber", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/menber.png");
    VGlobal::icon_path.insert("template", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/template.png");
    VGlobal::icon_path.insert("label", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/label.png");
    VGlobal::icon_path.insert("titlebar_close_icon", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/titlebar_close_icon.png");
    VGlobal::icon_path.insert("titlebar_normal_icon", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/titlebar_normal_icon.png");
    VGlobal::icon_path.insert("dock_expand", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/dock_expand.png");
    VGlobal::icon_path.insert("title_search", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/title_search.png");
    VGlobal::icon_path.insert("prototype", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/prototype.png");
    VGlobal::icon_path.insert("external_dependence", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/external_dependence.png");
    VGlobal::icon_path.insert("Modular", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/Modular.png");
    VGlobal::icon_path.insert("load", VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/icon/load.gif");
}

void MainWindow::init_action_icon()
{
    VGlobal::action.value("advance")->setIcon(QIcon(VGlobal::icon_path.value("advance")));
    VGlobal::action.value("retreat")->setIcon(QIcon(VGlobal::icon_path.value("retreat")));
    VGlobal::action.value("new_project")->setIcon(QIcon(VGlobal::icon_path.value("new_project")));
    VGlobal::action.value("open_project")->setIcon(QIcon(VGlobal::icon_path.value("file_open")));
    VGlobal::action.value("close_file")->setIcon(QIcon(VGlobal::icon_path.value("close_file")));
    VGlobal::action.value("save")->setIcon(QIcon(VGlobal::icon_path.value("save")));
    VGlobal::action.value("save_all")->setIcon(QIcon(VGlobal::icon_path.value("save_all")));
    VGlobal::action.value("exit")->setIcon(QIcon(VGlobal::icon_path.value("exit")));
    VGlobal::action.value("undo")->setIcon(QIcon(VGlobal::icon_path.value("undo")));
    VGlobal::action.value("redo")->setIcon(QIcon(VGlobal::icon_path.value("redo")));
    VGlobal::action.value("cut")->setIcon(QIcon(VGlobal::icon_path.value("cut")));
    VGlobal::action.value("copy")->setIcon(QIcon(VGlobal::icon_path.value("copy")));
    VGlobal::action.value("paste")->setIcon(QIcon(VGlobal::icon_path.value("paste")));
    VGlobal::action.value("comment")->setIcon(QIcon(VGlobal::icon_path.value("comment")));
    VGlobal::action.value("uncomment")->setIcon(QIcon(VGlobal::icon_path.value("uncomment")));
    VGlobal::action.value("left_ident")->setIcon(QIcon(VGlobal::icon_path.value("left_indent")));
    VGlobal::action.value("right_ident")->setIcon(QIcon(VGlobal::icon_path.value("right_indent")));
    VGlobal::action.value("biulder")->setIcon(QIcon(VGlobal::icon_path.value("builder")));
    VGlobal::action.value("new_file")->setIcon(QIcon(VGlobal::icon_path.value("new_file")));
    VGlobal::action.value("add_file")->setIcon(QIcon(VGlobal::icon_path.value("add_file")));
    VGlobal::action.value("get_more")->setIcon(QIcon(VGlobal::icon_path.value("help")));
    VGlobal::action.value("setting_file")->setIcon(QIcon(VGlobal::icon_path.value("setting")));
    VGlobal::action.value("export_file")->setIcon(QIcon(VGlobal::icon_path.value("export")));
    VGlobal::action.value("delete")->setIcon(QIcon(VGlobal::icon_path.value("delete")));
    VGlobal::action.value("access_file_homepage")->setIcon(QIcon(VGlobal::icon_path.value("access_webpage")));
    VGlobal::action.value("access_project_homepage")->setIcon(QIcon(VGlobal::icon_path.value("access_webpage")));
    VGlobal::action.value("rename")->setIcon(QIcon(VGlobal::icon_path.value("rename")));
    VGlobal::action.value("open_to_path")->setIcon(QIcon(VGlobal::icon_path.value("open_to_dir")));
    VGlobal::action.value("set_project_active")->setIcon(QIcon(VGlobal::icon_path.value("setting")));
    VGlobal::action.value("close_project")->setIcon(QIcon(VGlobal::icon_path.value("close_project")));
    VGlobal::action.value("search")->setIcon(QIcon(VGlobal::icon_path.value("search")));
    VGlobal::action.value("project_pack")->setIcon(QIcon(VGlobal::icon_path.value("pack")));
    VGlobal::action.value("code_format")->setIcon(QIcon(VGlobal::icon_path.value("code_format")));
    VGlobal::action.value("project_attribute")->setIcon(QIcon(VGlobal::icon_path.value("project_attribute")));
    VGlobal::action.value("setting")->setIcon(QIcon(VGlobal::icon_path.value("setting")));
    VGlobal::action.value("startpage")->setIcon(QIcon(VGlobal::icon_path.value("startpage")));
    VGlobal::action.value("project_build")->setIcon(QIcon(VGlobal::icon_path.value("builder")));
    VGlobal::action.value("new_folder")->setIcon(QIcon(VGlobal::icon_path.value("new_folder")));
    VGlobal::action.value("textedit_format")->setIcon(QIcon(VGlobal::icon_path.value("code_format")));
    VGlobal::action.value("foldAll")->setIcon(QIcon(VGlobal::icon_path.value("fold")));
    VGlobal::action.value("expandedAll")->setIcon(QIcon(VGlobal::icon_path.value("expanded")));
    VGlobal::action.value("jump")->setIcon(QIcon(VGlobal::icon_path.value("jump")));
    VGlobal::action.value("environmental")->setIcon(QIcon(VGlobal::icon_path.value("environment")));
    VGlobal::action.value("textedit_behavior")->setIcon(QIcon(VGlobal::icon_path.value("behavior")));
    VGlobal::action.value("textedit_format")->setIcon(QIcon(VGlobal::icon_path.value("code_format")));
    VGlobal::action.value("intelligence")->setIcon(QIcon(VGlobal::icon_path.value("calltip")));
    VGlobal::action.value("shortcut")->setIcon(QIcon(VGlobal::icon_path.value("shortcut")));
    VGlobal::action.value("search_pre")->setIcon(QIcon(VGlobal::icon_path.value("search_pre")));
    VGlobal::action.value("search_next")->setIcon(QIcon(VGlobal::icon_path.value("search_next")));
    VGlobal::action.value("search_replace")->setIcon(QIcon(VGlobal::icon_path.value("search_replace")));
    VGlobal::action.value("search_replace_all")->setIcon(QIcon(VGlobal::icon_path.value("search_replace_all")));
    VGlobal::action.value("questions")->setIcon(QIcon(VGlobal::icon_path.value("help")));
    VGlobal::action.value("source_content")->setIcon(QIcon(VGlobal::icon_path.value("content")));
    VGlobal::action.value("tools_path")->setIcon(QIcon(VGlobal::icon_path.value("tool")));
    VGlobal::action.value("setting")->setIcon(QIcon(VGlobal::icon_path.value("setting")));
}

void MainWindow::init_action_shortCut()
{
    VGlobal::action.value("new_project")->setShortcut(VGlobal::shortcut.value("创建项目"));
    VGlobal::action.value("open_project")->setShortcut(VGlobal::shortcut.value("打开项目"));
    VGlobal::action.value("advance")->setShortcut(VGlobal::shortcut.value("前进"));
    VGlobal::action.value("retreat")->setShortcut(VGlobal::shortcut.value("后退"));
    VGlobal::action.value("close_file")->setShortcut(VGlobal::shortcut.value("关闭文件"));
    VGlobal::action.value("save")->setShortcut(VGlobal::shortcut.value("保存"));
    VGlobal::action.value("save_all")->setShortcut(VGlobal::shortcut.value("全部保存"));
    VGlobal::action.value("undo")->setShortcut(VGlobal::shortcut.value("撤销"));
    VGlobal::action.value("redo")->setShortcut(VGlobal::shortcut.value("重复"));
    VGlobal::action.value("cut")->setShortcut(VGlobal::shortcut.value("剪切"));
    VGlobal::action.value("copy")->setShortcut(VGlobal::shortcut.value("复制"));
    VGlobal::action.value("paste")->setShortcut(VGlobal::shortcut.value("粘贴"));
    VGlobal::action.value("comment")->setShortcut(VGlobal::shortcut.value("注释"));
    VGlobal::action.value("uncomment")->setShortcut(VGlobal::shortcut.value("取消注释"));
    VGlobal::action.value("delete")->setShortcut(VGlobal::shortcut.value("删除"));
    VGlobal::action.value("search")->setShortcut(VGlobal::shortcut.value("搜索"));
    VGlobal::action.value("code_format")->setShortcut(VGlobal::shortcut.value("代码排版"));
    VGlobal::action.value("foldAll")->setShortcut(VGlobal::shortcut.value("全部折叠"));
    VGlobal::action.value("expandedAll")->setShortcut(VGlobal::shortcut.value("全部展开"));
    VGlobal::action.value("jump")->setShortcut(VGlobal::shortcut.value("快速跳转"));
    VGlobal::action.value("search_pre")->setShortcut(VGlobal::shortcut.value("搜索上一个"));
    VGlobal::action.value("search_next")->setShortcut(VGlobal::shortcut.value("搜索下一个"));
    VGlobal::action.value("search_replace")->setShortcut(VGlobal::shortcut.value("替换"));
    VGlobal::action.value("search_replace_all")->setShortcut(VGlobal::shortcut.value("全部替换"));
    VGlobal::action.value("biulder")->setShortcut(VGlobal::shortcut.value("生成"));
}

void MainWindow::init_action()
{
    VGlobal::action.insert("advance", new QAction("后退", this));
    VGlobal::action.insert("retreat", new QAction("前进", this));
    VGlobal::action.insert("new_project", new QAction("新建", this));
    VGlobal::action.insert("open_project", new QAction("打开", this));
    VGlobal::action.insert("close_file", new QAction("关闭", this));
    VGlobal::action.insert("save", new QAction("保存", this));
    VGlobal::action.insert("save_all", new QAction("全部保存", this));
    VGlobal::action.insert("exit", new QAction("退出", this));
    VGlobal::action.insert("undo", new QAction("撤销", this));
    VGlobal::action.insert("redo", new QAction("重复", this));
    VGlobal::action.insert("cut", new QAction("剪切", this));
    VGlobal::action.insert("copy", new QAction("复制", this));
    VGlobal::action.insert("paste", new QAction("粘贴", this));
    VGlobal::action.insert("comment", new QAction("注释", this));
    VGlobal::action.insert("uncomment", new QAction("取消注释", this));
    VGlobal::action.insert("left_ident", new QAction("左缩进", this));
    VGlobal::action.insert("right_ident", new QAction("右缩进", this));
    VGlobal::action.insert("biulder", new QAction("生成", this));
    VGlobal::action.insert("new_file", new QAction("新建文件", this));
    VGlobal::action.insert("add_file", new QAction("添加现有文件", this));
    VGlobal::action.insert("get_more", new QAction("获取更多", this));
    VGlobal::action.insert("setting_file", new QAction("配置文件", this));
    VGlobal::action.insert("export_file", new QAction("导出文件", this));
    VGlobal::action.insert("delete", new QAction("删除", this));
    VGlobal::action.insert("access_file_homepage", new QAction("访问文件主页", this));
    VGlobal::action.insert("access_project_homepage", new QAction("访问项目主页", this));
    VGlobal::action.insert("rename", new QAction("重命名", this));
    VGlobal::action.insert("open_to_path", new QAction("打开所在文件夹", this));
    VGlobal::action.insert("set_project_active", new QAction("设置为活动项目", this));
    VGlobal::action.insert("close_project", new QAction("关闭项目", this));
    VGlobal::action.insert("search", new QAction("搜索和替换", this));
    VGlobal::action.insert("project_pack", new QAction("打包项目", this));
    VGlobal::action.insert("code_format", new QAction("代码排版", this));
    VGlobal::action.insert("project_attribute", new QAction("属性", this));
    VGlobal::action.insert("setting", new QAction("选项", this));
    VGlobal::action.insert("startpage", new QAction("起始页", this));
    VGlobal::action.insert("project_build", new QAction("生成", this));
    VGlobal::action.insert("new_folder", new QAction("新建文件夹", this));
    VGlobal::action.insert("environmental", new QAction("环境", this));
    VGlobal::action.insert("textedit_behavior", new QAction("行为", this));
    VGlobal::action.insert("textedit_format", new QAction("代码排版", this));
    VGlobal::action.insert("intelligence", new QAction("智能提示", this));
    VGlobal::action.insert("shortcut", new QAction("快捷键", this));
    VGlobal::action.insert("foldAll", new QAction("全部折叠", this));
    VGlobal::action.insert("expandedAll", new QAction("全部展开", this));
    VGlobal::action.insert("jump", new QAction("快速跳转", this));
    VGlobal::action.insert("search_pre", new QAction("搜索上一个", this));
    VGlobal::action.insert("search_next", new QAction("搜索下一个", this));
    VGlobal::action.insert("search_replace", new QAction("替换", this));
    VGlobal::action.insert("search_replace_all", new QAction("全部替换", this));
    VGlobal::action.insert("questions", new QAction("提问", this));
    VGlobal::action.insert("source_content", new QAction("编译信息", this));
    VGlobal::action.insert("tools_path", new QAction("工具路径", this));
    VGlobal::action.insert("setting", new QAction("设置", this));

    VGlobal::action.value("advance")->setToolTip("后退");
    VGlobal::action.value("retreat")->setToolTip("前进");
    VGlobal::action.value("new_project")->setToolTip("新建");
    VGlobal::action.value("open_project")->setToolTip("打开");
    VGlobal::action.value("close_file")->setToolTip("关闭");
    VGlobal::action.value("save")->setToolTip("保存");
    VGlobal::action.value("save_all")->setToolTip("全部保存");
    VGlobal::action.value("exit")->setToolTip("退出");
    VGlobal::action.value("undo")->setToolTip("撤销");
    VGlobal::action.value("redo")->setToolTip("重复");
    VGlobal::action.value("cut")->setToolTip("剪切");
    VGlobal::action.value("copy")->setToolTip("复制");
    VGlobal::action.value("paste")->setToolTip("粘贴");
    VGlobal::action.value("comment")->setToolTip("注释");
    VGlobal::action.value("uncomment")->setToolTip("取消注释");
    VGlobal::action.value("left_ident")->setToolTip("左缩进");
    VGlobal::action.value("right_ident")->setToolTip("右缩进");
    VGlobal::action.value("biulder")->setToolTip("生成");
    VGlobal::action.value("new_file")->setToolTip("新建文件");
    VGlobal::action.value("add_file")->setToolTip("添加现有文件");
    VGlobal::action.value("get_more")->setToolTip("获取更多");
    VGlobal::action.value("setting_file")->setToolTip("配置文件");
    VGlobal::action.value("export_file")->setToolTip("导出文件");
    VGlobal::action.value("delete")->setToolTip("删除");
    VGlobal::action.value("access_file_homepage")->setToolTip("访问文件主页");
    VGlobal::action.value("access_project_homepage")->setToolTip("访问项目主页");
    VGlobal::action.value("rename")->setToolTip("重命名");
    VGlobal::action.value("open_to_path")->setToolTip("打开所在文件夹");
    VGlobal::action.value("set_project_active")->setToolTip("设置为活动项目");
    VGlobal::action.value("close_project")->setToolTip("关闭项目");
    VGlobal::action.value("search")->setToolTip("搜索和替换");
    VGlobal::action.value("search")->setShortcut(QKeySequence("Ctrl+F"));
    VGlobal::action.value("project_pack")->setToolTip("打包项目");
    VGlobal::action.value("code_format")->setToolTip("代码排版");
    VGlobal::action.value("project_attribute")->setToolTip("属性");
    VGlobal::action.value("setting")->setToolTip("选项");
    VGlobal::action.value("startpage")->setToolTip("起始页");
    VGlobal::action.value("project_build")->setToolTip("起始页生成");
    VGlobal::action.value("new_folder")->setToolTip("新建文件夹");
    VGlobal::action.value("setting")->setToolTip("设置");

    QObject::connect(VGlobal::action.value("advance"), &QAction::triggered, this, &MainWindow::on_action_advance_triggered);
    QObject::connect(VGlobal::action.value("retreat"), &QAction::triggered, this, &MainWindow::on_action_retreat_triggered);
    QObject::connect(VGlobal::action.value("new_project"), &QAction::triggered, this, &MainWindow::on_action_new_project_triggered);
    QObject::connect(VGlobal::action.value("open_project"), &QAction::triggered, this, &MainWindow::on_action_open_project_triggered);
    QObject::connect(VGlobal::action.value("close_file"), &QAction::triggered, this, &MainWindow::on_action_close_file_triggered);
    QObject::connect(VGlobal::action.value("save"), &QAction::triggered, this, &MainWindow::on_action_save_triggered);
    QObject::connect(VGlobal::action.value("save_all"), &QAction::triggered, this, &MainWindow::on_action_save_all_triggered);
    QObject::connect(VGlobal::action.value("exit"), &QAction::triggered, this, &MainWindow::on_action_exit_triggered);
    QObject::connect(VGlobal::action.value("undo"), &QAction::triggered, this, &MainWindow::on_action_undo_triggered);
    QObject::connect(VGlobal::action.value("redo"), &QAction::triggered, this, &MainWindow::on_action_redo_triggered);
    QObject::connect(VGlobal::action.value("cut"), &QAction::triggered, this, &MainWindow::on_action_cut_triggered);
    QObject::connect(VGlobal::action.value("copy"), &QAction::triggered, this, &MainWindow::on_action_copy_triggered);
    QObject::connect(VGlobal::action.value("paste"), &QAction::triggered, this, &MainWindow::on_action_paste_triggered);
    QObject::connect(VGlobal::action.value("comment"), &QAction::triggered, this, &MainWindow::on_action_comment_triggered);
    QObject::connect(VGlobal::action.value("uncomment"), &QAction::triggered, this, &MainWindow::on_action_uncomment_triggered);
    QObject::connect(VGlobal::action.value("left_ident"), &QAction::triggered, this, &MainWindow::on_action_left_ident_triggered);
    QObject::connect(VGlobal::action.value("right_ident"), &QAction::triggered, this, &MainWindow::on_action_right_ident_triggered);
    QObject::connect(VGlobal::action.value("biulder"), &QAction::triggered, this, &MainWindow::on_action_biulder_triggered);
    QObject::connect(VGlobal::action.value("new_file"), &QAction::triggered, this, &MainWindow::on_action_new_file);
//    QObject::connect(VGlobal::action.value("add_file"), &QAction::triggered, this, &MainWindow::on_action_add_file_triggered);
    QObject::connect(VGlobal::action.value("get_more"), &QAction::triggered, this, &MainWindow::on_action_get_more);
//    QObject::connect(VGlobal::action.value("setting_file"), &QAction::triggered, this, &MainWindow::on_action_setting_file);
    QObject::connect(VGlobal::action.value("export_file"), &QAction::triggered, this, &MainWindow::on_action_export_file);
    QObject::connect(VGlobal::action.value("delete"), &QAction::triggered, this, &MainWindow::on_action_delete_triggered);
    QObject::connect(VGlobal::action.value("access_file_homepage"), &QAction::triggered, this, &MainWindow::on_action_access_file_homepage);
    QObject::connect(VGlobal::action.value("access_project_homepage"), &QAction::triggered, this, &MainWindow::on_action_access_project_homepage);
    QObject::connect(VGlobal::action.value("rename"), &QAction::triggered, this, &MainWindow::on_action_rename);
    QObject::connect(VGlobal::action.value("open_to_path"), &QAction::triggered, this, &MainWindow::on_action_open_to_dir);
//    QObject::connect(VGlobal::action.value("set_project_active"), &QAction::triggered, this, &MainWindow::on_action_set_project_active_triggered);
    QObject::connect(VGlobal::action.value("close_project"), &QAction::triggered, this, &MainWindow::on_action_close_project_triggered);
    QObject::connect(VGlobal::action.value("search"), &QAction::triggered, this, &MainWindow::on_action_search_triggered);
    QObject::connect(VGlobal::action.value("project_pack"), &QAction::triggered, this, &MainWindow::on_action_project_pack);
    QObject::connect(VGlobal::action.value("code_format"), &QAction::triggered, this, &MainWindow::on_action_code_format);
    QObject::connect(VGlobal::action.value("project_attribute"), &QAction::triggered, this, &MainWindow::on_action_project_attribute);
//    QObject::connect(VGlobal::action.value("setting"), &QAction::triggered, this, &MainWindow::on_action_setting_trggered);
    QObject::connect(VGlobal::action.value("startpage"), &QAction::triggered, this, &MainWindow::on_action_startpage_trggered);
    QObject::connect(VGlobal::action.value("project_build"), &QAction::triggered, this, &MainWindow::on_action_project_build_trggered);
//    QObject::connect(VGlobal::action.value("new_folder"), &QAction::triggered, this, &MainWindow::on_action_new_folder_trggered);
    QObject::connect(VGlobal::action.value("foldAll"), &QAction::triggered, this, &MainWindow::on_action_foldAll_trggered);
    QObject::connect(VGlobal::action.value("expandedAll"), &QAction::triggered, this, &MainWindow::on_action_expandedAll_trggered);
    QObject::connect(VGlobal::action.value("jump"), &QAction::triggered, this, &MainWindow::on_action_jump_trggered);
    QObject::connect(VGlobal::action.value("search_pre"), &QAction::triggered, this, &MainWindow::on_action_search_pre_trggered);
    QObject::connect(VGlobal::action.value("search_next"), &QAction::triggered, this, &MainWindow::on_action_search_next_trggered);
    QObject::connect(VGlobal::action.value("search_replace"), &QAction::triggered, this, &MainWindow::on_action_search_replace_trggered);
    QObject::connect(VGlobal::action.value("search_replace_all"), &QAction::triggered, this, &MainWindow::on_action_search_replace_all_trggered);
    QObject::connect(VGlobal::action.value("questions"), &QAction::triggered, this, &MainWindow::on_action_questions_trggered);
    QObject::connect(VGlobal::action.value("source_content"), &QAction::triggered, this, &MainWindow::on_source_content_trggered);
//    QObject::connect(VGlobal::action.value("tools_path"), &QAction::triggered, this, &MainWindow::on_tools_path_trggered);
    QObject::connect(VGlobal::action.value("setting"), &QAction::triggered, this, &MainWindow::on_action_setting_trggered);
}

void MainWindow::init_main_toolbar()
{
    ui->mainToolBar->setObjectName("toolbar_qss");
    ui->mainToolBar->setWindowTitle("工具条");
    ui->mainToolBar->setIconSize(QSize(16, 16));
    ui->mainToolBar->addAction(VGlobal::action.value("retreat"));
    ui->mainToolBar->addAction(VGlobal::action.value("advance"));

    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("new_project"));
    ui->mainToolBar->addAction(VGlobal::action.value("open_project"));
    ui->mainToolBar->addAction(VGlobal::action.value("save"));
    ui->mainToolBar->addAction(VGlobal::action.value("save_all"));

    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("cut"));
    ui->mainToolBar->addAction(VGlobal::action.value("copy"));
    ui->mainToolBar->addAction(VGlobal::action.value("paste"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("undo"));
    ui->mainToolBar->addAction(VGlobal::action.value("redo"));

    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("comment"));
    ui->mainToolBar->addAction(VGlobal::action.value("uncomment"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("left_ident"));
    ui->mainToolBar->addAction(VGlobal::action.value("right_ident"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("foldAll"));
    ui->mainToolBar->addAction(VGlobal::action.value("expandedAll"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("code_format"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("search"));
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(VGlobal::action.value("biulder"));
}

void MainWindow::init_menubar()
{
    ui->menuBar->setObjectName("main_menubar");
    _menubar_project = ui->menuBar->addMenu("文件(&F)");
    _menubar_edit = ui->menuBar->addMenu("编辑(&E)");
    _menubar_search = ui->menuBar->addMenu("搜索(&S)");
    _menubar_biulder = ui->menuBar->addMenu("编译(&C)");
    _menubar_tool = ui->menuBar->addMenu("工具(&T)");
//    _menubar_setting = ui->menuBar->addMenu("设置(&U)");
    _menubar_help = ui->menuBar->addMenu("帮助(&H)");


    _menubar_project->addAction(VGlobal::action.value("new_project"));
    _menubar_project->addAction(VGlobal::action.value("open_project"));
    _menubar_project->addAction(VGlobal::action.value("startpage"));
    _menubar_project->addAction(VGlobal::action.value("close_file"));
    _menubar_project->addSeparator();
    _menubar_project->addAction(VGlobal::action.value("save"));
    _menubar_project->addAction(VGlobal::action.value("save_all"));
    _menubar_project->addAction(VGlobal::action.value("exit"));

    _menubar_edit->addAction(VGlobal::action.value("undo"));
    _menubar_edit->addAction(VGlobal::action.value("redo"));
    _menubar_edit->addSeparator();
    _menubar_edit->addAction(VGlobal::action.value("paste"));
    _menubar_edit->addAction(VGlobal::action.value("copy"));
    _menubar_edit->addAction(VGlobal::action.value("cut"));
    _menubar_edit->addAction(VGlobal::action.value("delete"));
    _menubar_edit->addSeparator();
    _menubar_edit->addAction(VGlobal::action.value("comment"));
    _menubar_edit->addAction(VGlobal::action.value("uncomment"));
    _menubar_edit->addSeparator();
    _menubar_edit->addAction(VGlobal::action.value("foldAll"));
    _menubar_edit->addAction(VGlobal::action.value("expandedAll"));
    _menubar_edit->addSeparator();
    _menubar_edit->addAction(VGlobal::action.value("code_format"));
    _menubar_edit->addSeparator();
    _menubar_edit->addAction(VGlobal::action.value("jump"));

    _menubar_search->addAction(VGlobal::action.value("search_pre"));
    _menubar_search->addAction(VGlobal::action.value("search_next"));
    _menubar_search->addAction(VGlobal::action.value("search_replace"));
    _menubar_search->addAction(VGlobal::action.value("search_replace_all"));
    _menubar_search->addAction(VGlobal::action.value("search"));

    // _menubar_setting->addAction(VGlobal::action.value("setting"));
//    _menubar_setting->addAction(VGlobal::action.value("environmental"));
//    _menubar_setting->addMenu(_menu_textedit_setting);
//    _menubar_setting->addAction(VGlobal::action.value("intelligence"));
//    _menubar_setting->addAction(VGlobal::action.value("shortcut"));
//    _menubar_setting->addAction(VGlobal::action.value("tools_path"));

    _menubar_biulder->addAction(VGlobal::action.value("biulder"));

    _menubar_help->addAction(VGlobal::action.value("get_more"));
}

void MainWindow::init_tool_menu()
{
    foreach(QAction *action, m_tool_actoin_list)
    {
        delete action;
    }

    m_tool_actoin_list.clear();
    QString text = VFunctions::read_file_text(VGlobal::config_dir+"/tools.txt");
    text = text.replace("<AppPath>", QCoreApplication::applicationDirPath());

    QStringList list = text.split("\r\n");
    foreach(QString path, list)
    {
        path = path.trimmed();
        if(path.isEmpty() || path.at(0) == '/')
        {
            continue;
        }

//        qDebug() << path;

        QFileInfo fileInfo(path);
        auto action = new QAction(this);
        action->setText(fileInfo.fileName());
        QObject::connect(action, QAction::triggered,[=](){
            QDesktopServices::openUrl(QUrl::fromLocalFile(path));
        });
        // 设置icon 图标
//            QPixmap pixmap = QFileIconProvider().icon(fileInfo).pixmap(32, 32);
//            pixmap.save("d:/1.png");
//            action->setIcon(QFileIconProvider().icon(fileInfo));

        action->setIcon(QIcon(VGlobal::icon_path.value("exe")));
        _menubar_tool->addAction(action);
        // append list
        m_tool_actoin_list.append(action);
    }
    _menubar_tool->adjustSize();
    _menubar_tool->addAction(VGlobal::action.value("setting"));
}

void MainWindow::init_statuebar()
{
    _line_label = new QLabel(this);
    _line_label->setObjectName("line_label");
//    _line_label->setFont(this->font());
    _line_label->hide();
    _column_label = new QLabel(this);
    _column_label->setObjectName("column_label");
//    _column_label->setFont(this->font());
    _column_label->hide();
    _sum_line_label = new QLabel(this);
    _sum_line_label->setObjectName("sum_line_label");
//    _sum_line_label->setFont(this->font());
    _sum_line_label->hide();
    set_document_info_label_text(0, 0, 0);

    // 输出
    auto btn_output = new QPushButton();
    btn_output->setText("1.输出");
    connect(btn_output, &QPushButton::clicked, [=](){
        _output_dock->setVisible(!_output_dock->isVisible());
    });

    // 错误列表
    auto btn_error_list = new QPushButton();
    btn_error_list->setText("2.错误列表");
    connect(btn_error_list, &QPushButton::clicked, [=](){
        _error_dock->setVisible(!_error_dock->isVisible());
    });

    auto toolbar = new QToolBar();
    toolbar->setObjectName("title_toolbar");
    toolbar->addWidget(btn_output);
    toolbar->addWidget(btn_error_list);

    // 论坛
    auto btn_bbs = new QPushButton();
    btn_bbs->setText("论坛");
    connect(btn_bbs, &QPushButton::clicked, [=](){
        QDesktopServices::openUrl(QString("https://www.51yishen.com"));
    });

    // 支撑作用
    auto w = new QWidget();
    w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    auto toolbar_after = new QToolBar();
    toolbar_after->setObjectName("title_toolbar");
    toolbar_after->addWidget(w);
    toolbar_after->addWidget(btn_bbs);

    ui->statusBar->setSizeGripEnabled(false);
    ui->statusBar->addPermanentWidget(toolbar, 50);
    ui->statusBar->addPermanentWidget(_line_label, 20);
    ui->statusBar->addPermanentWidget(_column_label, 20);
    ui->statusBar->addPermanentWidget(_sum_line_label, 20);
    ui->statusBar->addPermanentWidget(toolbar_after, 10);
    ui->statusBar->addPermanentWidget(new QLabel(), 1);
    ui->statusBar->setObjectName("statusbar_qss");
}

void MainWindow::init_content_menu()
{
    _content_menu = new QMenu(this);
}

void MainWindow::init_append_menu()
{
    _append_menu = new QMenu(this);

    _append_menu->setTitle("添加");
    _append_menu->setIcon(QIcon(VGlobal::icon_path.value("append")));
    _append_menu->addAction(VGlobal::action.value("new_file"));
    _append_menu->addAction(VGlobal::action.value("add_file"));
    _append_menu->addAction(VGlobal::action.value("new_folder"));
    _append_menu->addAction(VGlobal::action.value("get_more"));
}

void MainWindow::reload_testing()
{
    _reload_testing = true;
//    for(int i=0; i<_open_tabbar->count(); i++)
//    {
//        auto data = get_tab_data(i);
//        if(data != nullptr && data->_type == VGlobal::TabType::SCINTILLA)
//        {
//            uint last_time = QFileInfo(data->_path).lastModified().toTime_t();

//            if(last_time > data->_scintilla_data._last_modify_time)
//            {
//                auto result = QMessageBox::information(this, "重新加载", QString("路径 : %1 \r\n信息 : 文件被其他程序修改,是否重新载入?").arg(data->_path),
//                                                    QMessageBox::Yes | QMessageBox::No);
//                if (result == QMessageBox::Yes)
//                {
//                    // 重新载入
//                    reload_file(data->_path);
//                    data->_scintilla_data._last_modify_time = last_time;
//                }
//                else
//                {
//                    // 忽略本次载入
//                    data->_scintilla_data._last_modify_time = last_time;
//                }

//                // 后台重新文件修改时间, 防止后台重新加载导致前台和后台数据不统一
//                emit signal_set_file_last_time(data->_path, last_time);
//            }
//        }
//    }

    _reload_testing = false;

    // 后台文件载入检测
    emit signal_reload_testing();

//    for (auto i = 0; i < _document_switch.count(); i++)
//    {
//        VDocumentState& document_state = _document_switch[i];
//        uint last_time = QFileInfo(document_state._full_path).lastModified().toTime_t();
//        if (last_time > document_state._last_modify_time)
//        {
//            auto result = QMessageBox::information(this, "重新加载", QString("路径 : %1 \r\n信息 : 文件被其他程序修改,是否重新载入?").arg(document_state._full_path),
//                                                QMessageBox::Yes | QMessageBox::No);
//            if (result == QMessageBox::Yes)
//            {
//                // 重新载入
//                reload_file(document_state._full_path);
//                document_state._last_modify_time = last_time;
//            }
//            else
//            {
//                // 忽略本次载入
//                document_state._last_modify_time = last_time;
//            }

//            // 后台重新文件修改时间, 防止后台重新加载导致前台和后台数据不统一
//            emit signal_set_file_last_time(document_state._full_path, last_time);
//        }
//    }

}

void MainWindow::reload_file(QString path)
{
    // 判断当前路径是否打开了
    // 打开了才进行reload操作
//    if(open_tabbar_contain(path))
//    {
//        auto data = get_tab_data(path);
//        if(data != nullptr && data->_type == VGlobal::TabType::SCINTILLA)
//        {
//            QString text = VFunctions::read_file_text(path);
//            set_document_text(data->_scintilla_data._document, text);
//            data->_scintilla_data._modify = false;
//            emit signal_update_file_text(path, text);
//            _text_edit->setModified(false);
//        }
//    }
}

QString MainWindow::get_file_text(QString path)
{
    if(is_open_file(path))
    {
        return get_scintilla(path)->text();
    }
    else
    {
        return VFunctions::read_file_text(path);
    }
}

bool MainWindow::build_project(QString path)
{
    _output_widget->show();
    qDebug() << "build_project ->" << path;
    //清空 error warning
//    reset_error_warning();

    // 判断当前是否有打开了文档 如果打开了要更新数据到后台
//    if(_current_path.isEmpty() == false)
//    {
//        modify_testing();
//    }


    if (path.isEmpty() == false)
    {
        _output_widget->output_clear();
        _error_widget->table_clear();

        if(_error_widget->isVisible() == false)
        {
            _error_widget->show();
        }

        _error_widget->table_add_line_data(VErrorWidget::VTableItemType::INFO, -1,
                                            QDateTime::currentDateTime().toString("hh:mm:ss") + " 开始生成...",
                                            "", path, -1);

//        VFunctions::file_append_text(VGlobal::log_dir + "/build/" +  VFunctions::get_today() + ".txt",
//                                     "\r\n" + QDateTime::currentDateTime().toString("hh:mm:ss") + " 开始生成...");

        // 生成模块的代码
//        build_project_all_file(path);


       emit signal_build(path);
    }
    else
    {
        // 这里应该弹出提示
        QMessageBox::information(this, "提示", "项目为空");
    }
}

QString MainWindow::get_calltip_icon(int type)
{
    QString result;
    switch (type)
    {
    case VWords::KIND::PROTOTYPE:
    case VWords::KIND::FUNCTION:
        result = VGlobal::icon_path.value("function");
        break;
    case VWords::KIND::KEYWORD:
        result = VGlobal::icon_path.value("keyword");
        break;
    case VWords::KIND::ENUM:
        result = VGlobal::icon_path.value("enum");
        break;
    case VWords::KIND::ENUMERATOR:
        result = VGlobal::icon_path.value("enumerator");
        break;
    case VWords::KIND::TYPEDEF:
        result = VGlobal::icon_path.value("typedef");
        break;
    case VWords::KIND::STRUCT:
        result = VGlobal::icon_path.value("strcut");
        break;
    case VWords::KIND::UNION:
        result = VGlobal::icon_path.value("union");
        break;
    case VWords::KIND::MEMBER:
        result = VGlobal::icon_path.value("menber");
        break;
    case VWords::KIND::MARCO:
        result = VGlobal::icon_path.value("define");
        break;
    case VWords::KIND::PARAMETER:
        result = VGlobal::icon_path.value("parameter");
        break;
    case VWords::KIND::LOCAL:
        result = VGlobal::icon_path.value("local");
        break;
    case VWords::KIND::VARIABLE:
        result = VGlobal::icon_path.value("global");
        break;
    case VWords::KIND::FILE:
        result = VGlobal::icon_path.value("file_h");
        break;
    case VWords::KIND::FOLDER:
        result = VGlobal::icon_path.value("folder");
        break;
    case VWords::KIND::TEMPLATE:
        result = VGlobal::icon_path.value("template");
        break;
    case VWords::KIND::LABEL:
        result = VGlobal::icon_path.value("label");
        break;
    default:
        break;
    }
    return result;
}

QString MainWindow::calltip_item_text(VWords * p_word)
{
    QString result;
    switch (p_word->_kind)
    {
    case VWords::KIND::MARCO:
        result = p_word->_name + " : " + "宏定义";
        break;
    case VWords::KIND::PARAMETER:
        result = p_word->_name + " : " + p_word->_type_name;
        break;
    case VWords::KIND::LOCAL:
        result = p_word->_name + " : " + p_word->_type_name;
        break;
    case VWords::KIND::VARIABLE:
        result = p_word->_name + " : " + p_word->_type_name;
        break;
    default:
        result = p_word->_name;
        break;
    }
    return result;
    return QString();
}

void MainWindow::set_document_info_label_text(int row, int col, int rows)
{
    _line_label->setText("行:"+QString::number(row));
    _column_label->setText("列:"+QString::number(col));
    _sum_line_label->setText("总行数:"+QString::number(rows));
}

bool MainWindow::eventFilter(QObject * watched, QEvent * event)
{

    if(event->type() == QEvent::Resize)
    {
        if(_unlock_timer.isActive())
        {
            _unlock_timer.start();
        }
    }

    if(event->type() == QEvent::NonClientAreaMouseButtonPress
            && dockwidget != nullptr)
    {
        qDebug() << "NonClientAreaMouseButtonPress";
        int h = this->height();
        if(ui->mainToolBar != nullptr)
        {
//            ui->mainToolBar->
            h -= ui->mainToolBar->height();
        }
        if(ui->statusBar != nullptr)
        {
            h -= ui->statusBar->height();
        }
        if(ui->menuBar != nullptr)
        {
            h -= ui->menuBar->height();
        }

        _project_dock->slot_dock_lock(this->width(), h);
        dockwidget->slot_dock_lock(this->width(), h);
//        qDebug() << this->cursor().shape();
        _unlock_timer.start();
    }


    return QMainWindow::eventFilter(watched, event);
}

void MainWindow::readSettings()
{
    QSettings settings(VGlobal::config_dir + "/MyCompany.ini", QSettings::IniFormat);
    restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());

//    QSettings settings("MyCompany", "MyApp");
//    restoreGeometry(settings.value("geometry").toByteArray());
//    restoreState(settings.value("windowState").toByteArray());

//    QSettings settings("MyCompany", "MyApp");
//    settings.setValue("geometry", saveGeometry());
////    qDebug() << saveGeometry();
//    settings.setValue("windowState", saveState());
}

void MainWindow::closeEvent(QCloseEvent * event)
{
    _close_save_testing = true;
    _project_treewidget->close_project();

    QStringList list;
     foreach(VDockWidget* dock, _dockwidget_list)
     {
         auto scintilla = (VScintillaEx*)(dock->widget());
         if(scintilla->_modify)
             list.append(scintilla->_path);
     }

     VSaveQuestion dlg(this, list);
     int result = QDialog::Accepted;
     if(list.count() > 0)
     {
         result = dlg.exec();
     }

     if(result == QDialog::Accepted)
     {
         foreach(QString path, dlg._save_paths)
         {
             auto scintilla = get_scintilla(path);
             if(scintilla != nullptr)
             {
                 scintilla->save();
             }
         }
     }
     else
         event->ignore();
    _close_save_testing = false;


    VGlobal::input_tip->close();
    VGlobal::parameter_tip->close();
    VGlobal::mouse_hover_tip->close();
    _startpage_dock->show();
//    QSettings settings("MyCompany", "MyApp");
//    settings.setValue("geometry", saveGeometry());
//    settings.setValue("windowState", saveState());
//    qDebug() << saveGeometry();
    //QSettings settings("d:/MyCompany.ini", QSettings::IniFormat);
    QSettings settings(VGlobal::config_dir + "/MyCompany.ini", QSettings::IniFormat);
    settings.setValue("geometry", saveGeometry());
    settings.setValue("windowState", saveState());
}

void MainWindow::timerEvent(QTimerEvent *event)
{
//    if(event->timerId() == _idle_time)
//    {
//        _idle_count ++;
//        if(_idle_count > 5)
//        {
//            if(_current_path.length() > 0 && _text_edit->isModified())
//            {
//                //qDebug() << "modify_testing time";
//                modify_testing();
//            }
//            _idle_count = 0;
//        }
//    }
}

VDockWidget *MainWindow::get_first_scintilla_dockwidget()
{
    foreach(VDockWidget* dockwidget, _dockwidget_list)
    {
        if(dockwidget->widget()->objectName() == "scintilla")
        {
            return dockwidget;
        }
    }
    return nullptr;
}

VDockWidget *MainWindow::get_scintilla_dockwidget(QString path)
{
    foreach(VDockWidget* dockwidget, _dockwidget_list)
    {
        if(dockwidget->widget()->objectName() == "scintilla"
                && ((VScintillaEx*)(dockwidget->widget()))->_path == path)
        {
            return dockwidget;
        }
    }
    return nullptr;
}

VScintillaEx *MainWindow::get_scintilla(QString path)
{
    foreach(QDockWidget* dockwidget, _dockwidget_list)
    {
        if(dockwidget->widget()->objectName() == "scintilla"
                && ((VScintillaEx*)(dockwidget->widget()))->_path == path)
        {
            return ((VScintillaEx*)(dockwidget->widget()));
        }
    }
    return nullptr;
}

bool MainWindow::is_open_file(QString path)
{
    foreach(QDockWidget* dockwidget, _dockwidget_list)
    {
        if(dockwidget->widget()->objectName() == "scintilla")
        {
            if(((VScintillaEx*)(dockwidget->widget()))->_path == path)
            {
                return true;
            }
        }
    }
    qDebug() << "file no open:" << path;
    return false;
}

void MainWindow::open_file(QString path)
{
    if(is_open_file(path))
    {
        change_to_file(path);
        return;
    }

    QString text = VFunctions::read_file_text(path);

    // 创建 scintilla
    VScintillaEx *scintilla = new VScintillaEx(nullptr, path, text, VTabData::DocType::NORMAL);
    scintilla_connect(scintilla);
    scintilla->update_text();

    VDockWidget *dock = new VDockWidget(QFileInfo(path).fileName(), VDockWidget::CloseType::EMIT);
    dockwidget = dock;
//    dock->setMaximumWidth(100);
//    VTitleBarWidget *title = new VTitleBarWidget(this);
//    dock->setTitleBarWidget(title);

    dock->setWidget(scintilla);
    emit signal_update_file_text(path, text);

    auto sr = get_first_scintilla_dockwidget();
    if(sr != nullptr)
    {
        this->tabifyDockWidget(sr, dock);
        dock->setVisible(true);
        dock->raise();
    }
    else
    {
        this->tabifyDockWidget(_startpage_dock, dock);
        dock->setVisible(true);
        dock->raise();
//        QMainWindow::addDockWidget(Qt::RightDockWidgetArea, dock);
    }


    connect(this, &MainWindow::signal_dock_lock, dock, &VDockWidget::slot_dock_lock);
    connect(this, &MainWindow::signal_dock_unlock, dock, &VDockWidget::slot_dock_unlock);
    connect(scintilla, &VScintillaEx::signal_set_title, dock, &VDockWidget::slot_set_title);
    connect(dock, &VDockWidget::signal_close_clicked, [=](){
        if(scintilla->_modify)
        {
            bool result = scintilla->save_question();
            if(result == false)
            {
                return;
            }
        }

        slot_scintilla_update_info(scintilla->_path, -1, -1, -1);
        dock->setParent(nullptr);
        QMainWindow::removeDockWidget(dock);
        _dockwidget_list.removeOne(dock);

    });
    _dockwidget_list.append(dock);
    scintilla->setFocus();
}

void MainWindow::change_to_file(QString path)
{
    auto ptr = get_scintilla_dockwidget(path);
    if(ptr != nullptr)
    {
        ptr->setVisible(true);
        ptr->raise();
        ((VScintillaEx*)ptr->widget())->setFocus();
    }
}

void MainWindow::scintilla_connect(VScintillaEx *scintilla)
{
    QObject::connect(scintilla, &VScintillaEx::signal_inpout_tip, _background_system, &VBackgroundSystem::slot_input_tip);
    QObject::connect(scintilla, &VScintillaEx::signal_function_parameter_tip, _background_system, &VBackgroundSystem::slot_parameter_calltip);
    QObject::connect(scintilla, &VScintillaEx::signal_mouse_hover_tip, _background_system, &VBackgroundSystem::slot_mouse_hover_calltip);
    QObject::connect(scintilla, &VScintillaEx::signal_file_tip, _background_system, &VBackgroundSystem::slot_file_calltip);
    QObject::connect(scintilla, &VScintillaEx::signal_update_file_text, _background_system, &VBackgroundSystem::slot_update_file_data);
    QObject::connect(scintilla, &VScintillaEx::signal_update_file_last_modify_time, _background_system, &VBackgroundSystem::slot_set_file_last_time);
    QObject::connect(scintilla, &VScintillaEx::signal_reload_file, _background_system, &VBackgroundSystem::slot_reload_file);
//    QObject::connect(scintilla, &VScintillaEx::signal_modificationChanged, this, &MainWindow::slot_modificationChanged);
    QObject::connect(scintilla, &VScintillaEx::signal_select_word, _background_system, &VBackgroundSystem::slot_select_word);
    QObject::connect(scintilla, &VScintillaEx::signal_jump_request, _background_system, &VBackgroundSystem::slot_jump_request);
    QObject::connect(scintilla, &VScintillaEx::signal_hide_tip, this, &MainWindow::slot_hide_tip);
    QObject::connect(scintilla, &VScintillaEx::signal_append_navigation, this, &MainWindow::slot_append_navigation);
    QObject::connect(scintilla, &VScintillaEx::signal_scintilla_update_info, this, &MainWindow::slot_scintilla_update_info);
}

VScintillaEx *MainWindow::get_current_active_scintilla()
{
    foreach(QDockWidget* dockwidget, _dockwidget_list)
    {
        if(dockwidget->widget()->objectName() == "scintilla"
                && dockwidget->widget()->hasFocus())
        {
            return (VScintillaEx*)(dockwidget->widget());
        }
    }
    return nullptr;
}

void MainWindow::init_lock_timer()
{
    _unlock_timer.setSingleShot(true);
    _unlock_timer.setInterval(2000);
    connect(&_unlock_timer, &QTimer::timeout, [=](){
        if(dockwidget == nullptr) return;
        dockwidget->slot_dock_unlock();
        _project_dock->slot_dock_unlock();
        qDebug() << "unlock";
    });
}

void MainWindow::init_start_param()
{
    if(qApp->arguments().length() > 1)
    {
        if(QFileInfo(qApp->arguments()[1]).suffix() == "esln")
        {
            QString esln_path = qApp->arguments()[1];
            _project_treewidget->open_project(esln_path.replace("\\", "/"));
        }
    }

}

//void MainWindow::init_outline_dock()
//{
//    _outline_widget = new VOutlineWidget();
//    _outline_dock = new VDockWidget("大纲", VDockWidget::CloseType::HIDE);
//    _outline_dock->setWidget(_outline_widget);
//    _outline_dock->setObjectName("outline_dock");
//    QMainWindow::addDockWidget(Qt::LeftDockWidgetArea, _outline_dock);
//    connect(_project_treewidget, &VProjectTreeWidget::signal_current_path_changed, _outline_widget, &VOutlineWidget::slot_current_path_changed);
//    connect(_outline_widget, &VOutlineWidget::signal_outline_requst, _background_system, &VBackgroundSystem::slot_outline_requst);
//    connect(_background_system, &VBackgroundSystem::signal_update_outline, _outline_widget, &VOutlineWidget::slot_update_outline);
//    connect(_outline_widget, &VOutlineWidget::signal_jump, this, &MainWindow::slot_jump);
//}

bool MainWindow::jump_to(QString path, int line, int pos, bool append)
{
    if(line < 0 && pos <0)
    {
        return false;
    }

    open_file(path);
    change_to_file(path);
    auto scintilla = get_scintilla(path);
    scintilla->setFocus();
    if(scintilla == nullptr) return false;

    if(pos == -1)
    {
        scintilla->setSelect(scintilla->lineStartPos(line), scintilla->lineStartPos(line));
    }
    else
    {
        scintilla->setSelect(pos, pos);
    }
    if(append)
    {
        scintilla->append_navigation();
    }

    return true;
}

void MainWindow::init_output_dock()
{
    _output_widget = new VOutputWidget();
    _output_dock = new VDockWidget("输出", VDockWidget::CloseType::HIDE);
    _output_dock->setWidget(_output_widget);
    _output_dock->setObjectName("output_dock");
    _output_dock->setWindowTitle("输出");
    QMainWindow::addDockWidget(Qt::LeftDockWidgetArea, _output_dock);

    VToolBar *toolbar = _output_dock->_toolbar;
    toolbar->addWidget(_output_widget->_btn_clear);
}

void MainWindow::init_error_dock()
{
    _error_widget = new VErrorWidget();
    _error_dock = new VDockWidget("错误列表", VDockWidget::CloseType::HIDE);
    _error_dock->setWidget(_error_widget);
    _error_dock->setObjectName("error_dock");
    _error_dock->setWindowTitle("错误列表");
    QMainWindow::addDockWidget(Qt::LeftDockWidgetArea, _error_dock);


    VToolBar *toolbar = _error_dock->_toolbar;
    toolbar->addWidget(_error_widget->_checkbox_error);
    toolbar->addWidget(_error_widget->_checkbox_warning);
    toolbar->addWidget(_error_widget->_checkbox_info);

    connect(_error_widget, &VErrorWidget::signal_jump, this, &MainWindow::slot_jump);
}

void MainWindow::init_search_dock()
{
    _search_widget = new VSearchDlg(nullptr);
    _search_dock = new QDockWidget("搜索");
    _search_dock->setParent(this);
    _search_dock->setWidget(_search_widget);
    _search_dock->setObjectName("search_dock");
    _search_dock->setAllowedAreas(Qt::NoDockWidgetArea);
    _search_dock->setFloating(true);
    _search_dock->hide();
    connect(_search_widget, &VSearchDlg::signal_find, this, &MainWindow::slot_find);
    connect(this, &MainWindow::signal_set_title, _search_widget, &VSearchDlg::slot_show_text);
}
